﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using WebService.IServices;
using WebService.Model;

namespace WebService.Controllers
{
    [Route("api/Login")]
    [ApiController]
    [Authorize]
    public class LoginController : ControllerBase
    {
        readonly ILoginServices loginServices;
        private IConfiguration config;
        private readonly JwtConfig jwtModel = null;
        public LoginController(ILoginServices _loginServices, IConfiguration _config, IOptions<JwtConfig> _jwtModel)
        {
            loginServices = _loginServices;
            config = _config;
            jwtModel = _jwtModel.Value;
        }

        /// <summary>
        /// 登录界面，所有人都可以访问
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        [HttpPost("Login"), AllowAnonymous]
        public IActionResult Login([FromBody] Sys_User users)
        {
            IActionResult response = Unauthorized();
            var user = loginServices.Query(d => d.Name == users.Name && d.Password == users.Password).Result;
            var message = new MessageModel<Sys_User>();
            if (user != null && user.Count > 0)
            {
                var tokenString = BuildToken(user.First());
                message.Msg = null;
                message.Code = 200;
                response = Ok(new { Message = message, token = tokenString });
            }
            else
            {
                message.Msg = "未查询到该账户，或者该账户已经删除";
                message.Code = 1;
                response = Ok(new { Message = message, token = string.Empty });
            }
            return response;
        }


        [HttpGet("Logout"), AllowAnonymous]
        public IActionResult Logout()
        {
            var message = new MessageModel<Sys_User>();
            message.Msg = null;
            message.Code = 200;
            return Ok(new { Message = message });
        }

        /// 根据用户信息生成token
        /// <summary></summary>
        /// <param name="user"></param>
        /// <returns></returns>
        string BuildToken(Sys_User user)
        {
            //添加Claims信息
            var claims = new List<Claim>();
            claims.AddRange(new[] {
                new Claim(ClaimTypes.Name, user.Name),
                new Claim(JwtRegisteredClaimNames.Sub, user.Name),
                new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUniversalTime().ToString()),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            });

            DateTime now = DateTime.UtcNow;

            var jwtSecurityToken = new JwtSecurityToken(
               issuer: jwtModel.Issuer,
               audience: jwtModel.Audience,
               claims: claims,
               notBefore: now,
               expires: now.Add(TimeSpan.FromMinutes(jwtModel.Expiration)),
               signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtModel.SecurityKey)), SecurityAlgorithms.HmacSha256));
            //一个典型的JWT 字符串由三部分组成:

            //header: 头部,meta信息和算法说明
            //payload: 负荷(Claims), 可在其中放入自定义内容, 比如, 用户身份等
            //signature: 签名, 数字签名, 用来保证前两者的有效性

            //三者之间由.分隔, 由Base64编码.根据Bearer 认证规则, 添加在每一次http请求头的Authorization字段中, 这也是为什么每次这个字段都必须以Bearer jwy - token这样的格式的原因.
            return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        }
    }
}
